<template>
  <div class="org-chart-container" :class="loadingClass">
    <div
        v-if="!loading"
        ref="orgChartRoot"
        class="org-chart-node-children"
        :class="{
        vertical: direction === 'vertical',
        horizontal: direction === 'horizontal',
        'show-collapsable': showCollapsable,
        'one-branch': data.length === 1
      }"
    >

      <OrgTreeNode
          v-for="child in root.childNodes"
          :node="child"
          :root="root"
          orgStyle
          :show-collapsable="showCollapsable"
          :label-width="labelWidth"
          :label-height="labelHeight"
          :renderContent="renderContent"
          :nodeBtnContent="nodeBtnContent"
          :selected-key="selectedKey"
          :default-expand-all="defaultExpandAll"
          :node-key="nodeKey"
          :show-node-num="showNodeNum"
          :key="getNodeKey(child)"
          :props="props"
      ></OrgTreeNode>
    </div>
    <Spin fix v-if="loading" class="mb-10 mt-10">
      <Icon type="ios-loading" size=18 class="spin-icon-load"></Icon>
      <div>Loading</div>
    </Spin>
  </div>
</template>
<script>
import Vue from "vue";
import OrgTreeNode from "./OrgTreeNode.vue";
import TreeStore from "./model/tree-store.js";
import {getNodeKey} from "./model/util";

export default {
  name: "OrgTree",
  components: {
    OrgTreeNode,
  },
  provide() {
    return {
      orgEventBus: this.orgEventBus
    };
  },
  props: {
    data: {
      // 源数据
      required: true
    },
    leftData: {
      // 源数据
      type: Array
    },
    // 方向
    direction: {
      type: String,
      default: "vertical"
    },
    // 子节点是否可折叠
    showCollapsable: {
      type: Boolean,
      default: false
    },
    // 飞书 OKR 模式
    onlyBothTree: {
      type: Boolean,
      default: false
    },
    orgStyle: {
      type: Boolean,
      default: false
    },
    // 树节点的内容区的渲染 Function
    renderContent: Function,
    // 展开节点的内容渲染 Function
    nodeBtnContent: Function,
    // 显示节点数
    showNodeNum: Boolean,
    // 树节点区域的宽度
    labelWidth: [String, Number],
    // 树节点区域的高度
    labelHeight: [String, Number],
    // 树节点的样式
    labelClassName: [Function, String],
    // 当前选中节点样式
    currentLabelClassName: [Function, String],
    // 用来控制选择节点的字段名
    selectedKey: String,
    // 是否默认展开所有节点
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    // 当前选中的节点
    currentNodeKey: [String, Number],
    // 每个树节点用来作为唯一标识的属性，整棵树应该是唯一的
    nodeKey: String,
    defaultExpandedKeys: {
      type: Array
    },
    filterNodeMethod: Function,
    props: {
      default() {
        return {
          leftChildren: "leftChildren",
          children: "children",
          name: "name",
          status: "status",
          type: "type",
          selected: "selected",
          icon: "icon",
          isRelation: "isRelation",
          selectedCount: "selectedCount"
        };
      }
    },
    // 动画
    animate: {
      type: Boolean,
      default: false
    },
    animateName: {
      type: String,
      default: "okr-zoom-in-center"
    },
    animateDuration: {
      type: Number,
      default: 200
    },
    // 选项是否多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 开启后，文本将不换行，超出部分显示为省略号
    ellipsis: {
      type: Boolean,
      default: false
    },
    // 在按照长度截取下的文本最大字符数，超过则截取省略
    ellipsisLength: {
      type: Number,
      default: 20
    },
    // 是否开启拖拽调整行顺序，需配合 @on-drag-drop 事件使用
    draggable: {
      type: Boolean,
      default: false
    },
    // 是否加载中
    loading: {
      type: Boolean,
      default: false
    },
    // 是否支持关联
    relation: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    nodeClass() {
      return {
        findNode: null
      };
    },
    loadingClass() {
      let clsArr = [];
      if (this.loading) {
        clsArr.push("org-chart-container-loading")
      }
      return clsArr
    },
  },
  data() {
    return {
      orgEventBus: new Vue(),
      store: null,
      root: null
    };
  },
  created() {
    this.isTree = true;
    this.store = new TreeStore({
      key: this.nodeKey,
      data: this.data,
      leftData: this.leftData,
      props: this.props,
      defaultExpandedKeys: this.defaultExpandedKeys,
      showCollapsable: this.showCollapsable,
      currentNodeKey: this.currentNodeKey,
      defaultExpandAll: this.defaultExpandAll,
      filterNodeMethod: this.filterNodeMethod,
      labelClassName: this.labelClassName,
      currentLabelClassName: this.currentLabelClassName,
      onlyBothTree: this.onlyBothTree,
      direction: this.direction,
      animate: this.animate,
      animateName: this.animateName,
      multiple: this.multiple,
      ellipsis: this.ellipsis,
      ellipsisLength: this.ellipsisLength,
      draggable: this.draggable,
      loading: this.loading,
      relation: this.relation
    });
    this.root = this.store.root;
  },
  watch: {
    data(newVal) {
      this.store.setData(newVal);
    },
    defaultExpandedKeys(newVal) {
      this.store.defaultExpandedKeys = newVal;
      this.store.setDefaultExpandedKeys(newVal);
    }
  },
  methods: {
    filter(value) {
      if (!this.filterNodeMethod)
        throw new Error("[Tree] filterNodeMethod is required when filter");
      this.store.filter(value);
      if (this.onlyBothTree) {
        this.store.filter(value, "leftChildNodes");
      }
    },
    getNodeKey(node) {
      return getNodeKey(this.nodeKey, node.data);
    },
    // 通过 node 设置某个节点的当前选中状态
    setCurrentNode(node) {
      if (!this.nodeKey)
        throw new Error("[Tree] nodeKey is required in setCurrentNode");
      this.store.setUserCurrentNode(node);
    },
    // 根据 data 或者 key 拿到 Tree 组件中的 node
    getNode(data) {
      return this.store.getNode(data);
    },
    // 通过 key 设置某个节点的当前选中状态
    setCurrentKey(key) {
      if (!this.nodeKey)
        throw new Error("[Tree] nodeKey is required in setCurrentKey");
      this.store.setCurrentNodeKey(key);
    },
    remove(data) {
      this.store.remove(data);
    },
    // 获取当前被选中节点的 data
    getCurrentNode() {
      const currentNode = this.store.getCurrentNode();
      return currentNode ? currentNode.data : null;
    },
    getCurrentKey() {
      if (!this.nodeKey)
        throw new Error("[Tree] nodeKey is required in getCurrentKey");
      const currentNode = this.getCurrentNode();
      return currentNode ? currentNode[this.nodeKey] : null;
    },
    append(data, parentNode) {
      this.store.append(data, parentNode);
    },
    insertBefore(data, refNode) {
      this.store.insertBefore(data, refNode);
    },
    insertAfter(data, refNode) {
      this.store.insertAfter(data, refNode);
    },
    updateKeyChildren(key, data) {
      if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in updateKeyChild');
      this.store.updateChildren(key, data);
    },
    checkMove(evt) {
      console.log(evt)
      return true;
    },
    //开始拖拽事件
    onStart() {
      this.drag = true;
    },
    //拖拽结束事件
    onEnd() {
      this.drag = false;
    },
    // 根据 data 获取所有已选中
    getSelectedNode(data) {
      let arr = []
      this.store.getSelectedNode(arr, data)
      return arr;
    },
  }
};
</script>

<style>
@import "./model/transition.css";
@import "./model/org-tree.css";

.spin-icon-load {
  animation: ani-spin 1s linear infinite;
}

@keyframes ani-spin {
  from {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
